from pointLibrary import *
from math import *
import random
random.seed(0)
def noise(o,persist):
    a=[]
    n=2**(o)+4
    for i in range(n):
        a.append([])
        for j in range(n):
            a[i].append(random.random())
    def smoothNoise(x,y):
        corners = (a[x][y] + a[x+2][y] + a[x][y+2] + a[x+2][y+2] ) / 16
        sides   = (a[x][y+1] + a[x+2][y+1] + a[x+1][y]+a[x+1][y+2] ) / 8
        center = a[x+1][y+1]/4
        return corners + sides + center
    def interpNoise(wx,wy):
        intX= int(floor(wx))
        fracX= frac(wx)
        intY= int(floor(wy))
        fracY= frac(wy)
        v1=smoothNoise(intX,intY)
        v2=smoothNoise(intX+1,intY)
        v3=smoothNoise(intX,intY+1)
        v4=smoothNoise(intX+1,intY+1)
        i1=cosInterp(v1,v2,fracX)
        i2=cosInterp(v3,v4,fracX)
        return cosInterp(i1,i2,fracY)        
    def perlin(p):
        total = 0
        x=grid(p.x)
        y=grid(p.y)
        amp=1
        freq=1
        total=0
        d=0
        if x>=0 and x<=1 and y>=0 and y<=1:
            for i in range(o):
                d=d+amp
                total = total +interpNoise(x*freq,y*freq)*amp
                freq=freq*2
                amp=amp*persist
            return total/d
        else: return 0
    return perlin
def noise2(o,persist):
    a=[]
    n=2**(o)+4
    for i in range(n):
        a.append([])
        for j in range(n):
            a[i].append(random.random())
    def smoothNoise(x,y):
        corners = (a[x][y] + a[x+2][y] + a[x][y+2] + a[x+2][y+2] ) / 16
        sides   = (a[x][y+1] + a[x+2][y+1] + a[x+1][y]+a[x+1][y+2] ) / 8
        center = a[x+1][y+1]/4
        return corners + sides + center
    def interpNoise(wx,wy):
        intX= int(floor(wx))
        fracX= frac(wx)
        intY= int(floor(wy))
        fracY= frac(wy)
        #v1=smoothNoise(intX,intY)
        #v2=smoothNoise(intX+1,intY)
        #v3=smoothNoise(intX,intY+1)
        #v4=smoothNoise(intX+1,intY+1)
        #i1=cosInterp(v1,v2,fracX)
        #i2=cosInterp(v3,v4,fracX)
        #return cosInterp(i1,i2,fracY) 
        return a[intX][intY]       
    def perlin(p):
        total = 0
        x=grid(p.x)
        y=grid(p.y)
        amp=1
        freq=1
        total=0
        d=0
        if x>=0 and x<=1 and y>=0 and y<=1:
            for i in range(o):
                d=d+amp
                total = total +interpNoise(x*freq,y*freq)*amp
                freq=freq*2
                amp=amp*persist
            return total/d
        else: return 0
    return perlin
def cosInterp(a,b,x):
    ft=x*3.1415927
    f=(1-cos(ft))*.5
    return a*(1-f)+b*f
grid = lambda x:(x+1)/2.0

def noise3(o,persist,oct):
    a=[]
    n=2**(o)+4
    for i in range(n):
        a.append([])
        for j in range(n):
            a[i].append(random.random())
    def smoothNoise(x,y):
        corners = (a[x][y] + a[x+2][y] + a[x][y+2] + a[x+2][y+2] ) / 16
        sides   = (a[x][y+1] + a[x+2][y+1] + a[x+1][y]+a[x+1][y+2] ) / 8
        center = a[x+1][y+1]/4
        return corners + sides + center
    def interpNoise(wx,wy):
        intX= int(floor(wx))
        fracX= frac(wx)
        intY= int(floor(wy))
        fracY= frac(wy)
        #v1=smoothNoise(intX,intY)
        #v2=smoothNoise(intX+1,intY)
        #v3=smoothNoise(intX,intY+1)
        #v4=smoothNoise(intX+1,intY+1)
        #i1=cosInterp(v1,v2,fracX)
        #i2=cosInterp(v3,v4,fracX)
        #return cosInterp(i1,i2,fracY) 
        return a[intX][intY]       
    def perlin(p):
        total = 0
        x=grid(p.x)
        y=grid(p.y)
        amp=1
        freq=1
        total=0
        d=0
        if x>=0 and x<=1 and y>=0 and y<=1:
            for i in range(o):
                d=d+amp
                if i == oct:
                    total = total +interpNoise(x*freq,y*freq)*amp
                freq=freq*2
                amp=amp*persist
            return total/d
        else: return 0
    return perlin
def cosInterp(a,b,x):
    ft=x*3.1415927
    f=(1-cos(ft))*.5
    return a*(1-f)+b*f
grid = lambda x:(x+1)/2.0